/**
 * Created by chenwen on 17-3-25.
 * 整个支付流程如下：
 1.客户端向Appstore请求购买产品（假设产品信息已经取得），Appstore验证产品成功后，从用户的Apple账户余额中扣费。
 2.Appstore向客户端返回一段receipt-data，里面记录了本次交易的证书和签名信息。
 3.客户端向我们可以信任的游戏服务器提供receipt-data
 4.游戏服务器对receipt-data进行一次base64编码
 5.把编码后的receipt-data发往itunes.appstore进行验证
 6.itunes.appstore返回验证结果给游戏服务器
 7.游戏服务器对商品购买状态以及商品类型，向客户端发放相应的道具与推送数据更新通知
 这七个步骤实际上是一个很安全的流程了。那问题出在哪里呢？我们谈谈两种苹果IAP的验证模型。

 苹果反馈的状态码
 ·21000App Store无法读取你提供的JSON数据
 ·21002 收据数据不符合格式
 ·21003 收据无法被验证
 ·21004 你提供的共享密钥和账户的共享密钥不一致
 ·21005 收据服务器当前不可用
 ·21006 收据是有效的，但订阅服务已经过期。当收到这个信息时，解码后的收据信息也包含在返回内容中
 ·21007 收据信息是测试用（sandbox），但却被发送到产品环境中验证
 ·21008 收据信息是产品环境中使用，但却被发送到测试环境中验证
 先生产验证后测试验证，可以避免来回切换接口的麻烦。测试验证只要用你自己申请的测试appid的时候才会用到，
 用户不会拥有测试appid，所以不会走到测试验证这一步。即使生产验证出错，应该也不回返回21007状态吗。测试验证通过的用户名，
 充值金额最好用数据库记录下来，方便公司资金核对。
 */

var https = require("https"),
    querystring = require('querystring');

class IOS{
    /**
     * @param production 是否为生产环境
     */
    constructor(production){
        this.production = production;
    }
    request(options, data){
        let self = this;
        return new Promise(function(resolve, reject){
            let req = https.request(options, function(res){
                res.setEncoding('utf8');
                let str = "";
                res.on('data', function (chunk) {
                    console.log(chunk);
                    str += chunk;
                });
                res.on("end", function(){
                    var data = JSON.parse(str);
                    if(data.status == 21007 || data.status == 21008) {
                        self.production = !self.production;
                        self.validateNotify(receipt, cb);
                    }else{
                        resolve(JSON.parse(str));
                    }
                });
                res.on('error', function (error) {
                    reject(error);
                });
            });
            req.write(data);
            req.end();
        })
    }

    /**
     *通知验证
     * @param receipt ios回调数据
     * @return promise
     */
    notifyValidate(receipt){
        let receiptData_base64 = JSON.stringify(receipt);
        receiptData_base64  = new Buffer(receiptData_base64).toString("base64");
        let url = this.production ? 'buy.itunes.apple.com' : 'sandbox.itunes.apple.com';
        let receiptEnvelope = {
            "receipt-data": receiptData_base64
        };
        let receiptEnvelopeStr = JSON.stringify(receiptEnvelope);
        let options = {
            host: url,
            port: 443,
            path: '/verifyReceipt',
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Content-Length': Buffer.byteLength(receiptEnvelopeStr)
            }
        };
        return this.request(options, receiptEnvelopeStr);
}
}

module.exports = IOS;